#ifndef PAGE_H
#define PAGE_H

#include "bufmanager/BufPageManager.h"
#include "fileio/FileManager.h"
#include "utils/pagedef.h"
#include <vector>

using namespace std;

class Page {
private:
	BufPageManager* bpm;
	BufType buffer;
	int pageIndex;

public:
	static const int MAX_ADDRESS = 2000;

	Page(BufPageManager* bpm, int dbID, int pageID) {
		this->bpm = bpm;
		buffer = bpm->getPage(dbID, pageID, pageIndex);
	}

	unsigned int read(int index) {
		if (0 <= index && index < MAX_ADDRESS) {
			bpm->access(pageIndex);
			return buffer[index];
		} else {
			cout << "Out of boundary in Page::read" << endl;
		}
		return 0;
	}

	void write(int index, unsigned int value) {
		if (0 <= index && index < MAX_ADDRESS) {
			bpm->markDirty(pageIndex);
			buffer[index] = value;
		} else {
			cout << "Out of boundary in Page::write" << endl;
		}
	}

	void setRecord(int recordId, vector<unsigned int> data) {
		if (0 <= recordId && (recordId + 1) * data.size() <= MAX_ADDRESS) {
			bpm->markDirty(pageIndex);
			int cnt = 0;
			for (int i = recordId * data.size(); i < (recordId + 1) * data.size(); i++) {
				buffer[i] = data[cnt++];
			}
		} else {
			cout << "Out of boundary in Page::setRecord" << endl;
		}
	}

	vector<unsigned int> getRecord(int recordId, int recordLen) {
		vector<unsigned int> ret;

		if (0 <= recordId && (recordId + 1) * recordLen <= MAX_ADDRESS) {
			bpm->access(pageIndex);
			for (int i = recordId * recordLen; i < (recordId + 1) * recordLen; i++) {
				ret.push_back(buffer[i]);
			}
		} else {
			cout << "Out of boundary in Page::getRecord" << endl;
		}

		return ret;
	}

	void writeBack() {
		bpm->writeBack(pageIndex);
	}
};

#endif
